﻿using BLevy.Datos.Interfases;
using BLevy.Entidad;
using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Dapper;
using DapperExtensions;

namespace BLevy.Datos.Repositories
{
    public interface ICobradorRepository : IRepository<Cobrador>
    {
        IList<Cobrador> FindAllConLocalidadZona();
        IList<CobradorCobro> FindAllCobrosPendientesPagoPorCobrador(int cobrador_id);
        IList<CobradorCobro> FindAllCobrosPendientesPagoPorCobradorCondicional(int cobrador_id, string numero_cupon, DateTime? desde, DateTime? hasta);
        
        
    }

    public class CobradorRepository : ICobradorRepository
    {

        protected readonly IDbConnection _db;

        public CobradorRepository()
        {
            try
            {
                _db = new MySqlConnection(ConfigurationManager.ConnectionStrings["LEVYDB"].ToString());
            }
            catch(Exception e)
            {
                throw e;
            }
        }

        public IList<Cobrador> FindAll()
        {
            string query = "SELECT * FROM COBRADORES";

            try
            {
                using (IDbConnection _db = new MySqlConnection(ConfigurationManager.ConnectionStrings["LEVYDB"].ToString()))
                {
                    return _db.Query<Cobrador>(query).ToList();
                }
            }
            catch(Exception e)
            {
                throw e;
            }
        }

        public IQueryable<Cobrador> Find(System.Linq.Expressions.Expression<Func<Cobrador, bool>> predicate)
        {
            throw new NotImplementedException();
        }

        public Cobrador FindById(int id)
        {
            string query = "SELECT * FROM COBRADORES " +
                "WHERE ID = " + id;

            try
            {
                using (IDbConnection _db = new MySqlConnection(ConfigurationManager.ConnectionStrings["LEVYDB"].ToString()))
                {
                    return _db.Query<Cobrador>(query).SingleOrDefault();
                }
            }
            catch(Exception e)
            {
                throw e;
            }
        }

        public int Add(Cobrador newEntity)
        {
            string query = "INSERT INTO COBRADORES (FECHAREGISTRO, APELLIDO, NOMBRES, DOCUMENTO, CALLE, NUMERACION, " +
            "PISO, DEPARTAMENTO, LOCALIDAD_ID, ZONA_ID, TELEFONOPARTICULAR, TELEFONOCELULAR, EMAIL, COMISION, VIGENCIA, ACTIVO) " +
            "VALUES (@fecharegistro, @apellido, @nombres, @documento, @calle, @numeracion, @piso, @departamento, @localidad_id, " +
            "@zona_id, @telefonoparticular, @telefonocelular, @email, @comision, @vigencia, @activo)";

            try
            {
                using (IDbConnection _db = new MySqlConnection(ConfigurationManager.ConnectionStrings["LEVYDB"].ToString()))
                {
                    return _db.Execute(query, new
                    {
                        fecharegistro = newEntity.fecharegistro,
                        apellido = newEntity.apellido,
                        nombres = newEntity.nombres,
                        documento = newEntity.documento,
                        calle = newEntity.calle,
                        numeracion = newEntity.numeracion,
                        piso = newEntity.piso,
                        departamento = newEntity.departamento,
                        localidad_id = newEntity.localidad_id,
                        zona_id = newEntity.zona_id,
                        telefonoparticular = newEntity.telefonoparticular,
                        telefonocelular = newEntity.telefonocelular,
                        email = newEntity.email,
                        comision = newEntity.comision,
                        vigencia = newEntity.vigencia,
                        activo = newEntity.activo
                    });
                }
            }
            catch(Exception e)
            {
                throw e;
            }
        }

        public int Remove(int id)
        {
            string query = "UPDATE COBRADORES SET ACTIVO = 0 " +
                "WHERE ID = " + id;

            try
            {
                using (IDbConnection _db = new MySqlConnection(ConfigurationManager.ConnectionStrings["LEVYDB"].ToString()))
                {
                    return _db.Execute(query);
                }
            }
            catch(Exception e)
            {
                throw e;
            }
        }

        public int Modify(Cobrador entity)
        {
            string query = "UPDATE COBRADORES SET APELLIDO  =@apellido, NOMBRES = @nombres, DOCUMENTO = @documento, " +
                "CALLE = @calle, NUMERACION = @numeracion, PISO = @piso, DEPARTAMENTO = @departamento, " +
                "LOCALIDAD_ID = @localidad_id, ZONA_ID = @zona_id, TELEFONOPARTICULAR = @telefonoparticular, " +
                "TELEFONOCELULAR = @telefonocelular, EMAIL = @email, COMISION = @comision, VIGENCIA = @vigencia, ACTIVO = @activo " +                
                "WHERE id = @id";

            try
            {
                using (IDbConnection _db = new MySqlConnection(ConfigurationManager.ConnectionStrings["LEVYDB"].ToString()))
                {
                    return _db.Execute(query, new
                    {
                        apellido = entity.apellido,
                        nombres = entity.nombres,
                        documento = entity.documento,
                        calle = entity.calle,
                        numeracion = entity.numeracion,
                        piso = entity.piso,
                        departamento = entity.departamento,
                        localidad_id = entity.localidad_id,
                        zona_id = entity.zona_id,
                        telefonoparticular = entity.telefonoparticular,
                        telefonocelular = entity.telefonocelular,
                        email = entity.email,
                        comision = entity.comision,
                        vigencia = entity.vigencia,
                        activo = entity.activo,
                        id = entity.id
                    });
                }
            }
            catch(Exception e)
            {
                throw e;
            }
        }

        public IList<Cobrador> FindAllConLocalidadZona()
        {
            string query = "SELECT * FROM COBRADORES " +
                    "INNER JOIN LOCALIDADES ON LOCALIDADES.ID = COBRADORES.LOCALIDAD_ID " +
                    "INNER JOIN ZONAS ON ZONAS.ID = COBRADORES.ZONA_ID";

            try
            {
                using (IDbConnection _db = new MySqlConnection(ConfigurationManager.ConnectionStrings["LEVYDB"].ToString()))
                {
                    return _db.Query<Cobrador, Localidad, Zona, Cobrador>(query,
                        (cobrador, localidad, zona) =>
                        {
                            cobrador.localidad = localidad;
                            cobrador.zona = zona;
                            return cobrador;
                        }, splitOn: "id").ToList();
                }
            }
            catch(Exception e)
            {
                throw e;
            }
        }

        public IList<CobradorCobro> FindAllCobrosPendientesPagoPorCobrador(int cobrador_id)
        {
            const string query = "SELECT * FROM COBRADORESCOBROS " +
                "INNER JOIN COBRADORES ON COBRADORES.ID = COBRADORESCOBROS.COBRADOR_ID " +
                "INNER JOIN COBROS ON COBROS.ID = COBRADORESCOBROS.COBRO_ID " +
                "INNER JOIN CUPONES ON CUPONES.ID = COBROS.CUPON_ID " +
                "WHERE COBRADORESCOBROS.ESTADO  = 'I' AND COBRADORESCOBROS.COBRADOR_ID = @cobrador_id " +
                "ORDER BY COBRADORESCOBROS.FECHA_COBRO DESC";

            try
            {
                using (IDbConnection _db = new MySqlConnection(ConfigurationManager.ConnectionStrings["LEVYDB"].ToString()))
                {
                    return _db.Query<CobradorCobro, Cobrador, Cobro, Cupon, CobradorCobro>(query,
                        (cobrador_cobro, cobrador, cobro, cupon) =>
                        {
                            cobrador_cobro.cobrador = cobrador;
                            cobrador_cobro.cobro = cobro;
                            cobrador_cobro.cobro.cupon = cupon;
                            return cobrador_cobro;
                        }, new { cobrador_id = cobrador_id }, splitOn: "id").ToList();
                }
            }
            catch(Exception e)
            {
                throw e;
            }
        }

        public IList<CobradorCobro> FindAllCobrosPendientesPagoPorCobradorCondicional(int cobrador_id, string numero_cupon, DateTime? desde, DateTime? hasta)
        {
            const string query = "SELECT * FROM COBRADORESCOBROS " +
                "INNER JOIN COBRADORES ON COBRADORES.ID = COBRADORESCOBROS.COBRADOR_ID " +
                "INNER JOIN COBROS ON COBROS.ID = COBRADORESCOBROS.COBRO_ID " +
                "INNER JOIN CUPONES ON CUPONES.ID = COBROS.CUPON_ID " +
                "WHERE COBRADORESCOBROS.ESTADO  = 'I' AND COBRADORESCOBROS.COBRADOR_ID = @cobrador_id " +
                "AND ((CUPONES.NUMERO LIKE CONCAT('%', @numero_cupon, '%')) OR (@numero_cupon IS NULL)) " + 
                "AND ((CUPONES.FECHA_EMISION BETWEEN @desde AND @hasta) OR ((@desde IS NULL) OR (@hasta IS NULL))) " +
                "ORDER BY COBRADORESCOBROS.FECHA_COBRO DESC";

            try
            {

                using (IDbConnection _db = new MySqlConnection(ConfigurationManager.ConnectionStrings["LEVYDB"].ToString()))
                {
                    return _db.Query<CobradorCobro, Cobrador, Cobro, Cupon, CobradorCobro>(query,
                        (cobrador_cobro, cobrador, cobro, cupon) =>
                        {
                            cobrador_cobro.cobrador = cobrador;
                            cobrador_cobro.cobro = cobro;
                            cobrador_cobro.cobro.cupon = cupon;
                            return cobrador_cobro;
                        }, new
                        {
                            cobrador_id = cobrador_id,
                            numero_cupon = numero_cupon,
                            desde = desde,
                            hasta = hasta
                        }, splitOn: "id").ToList();
                }
            }
            catch (Exception e)
            {
                throw e;
            }
        }


    }
}


